package io.cici.cc.mybatis.lite.sql_source.scripting.tagHandler;

import io.cici.cc.mybatis.lite.builder.BuilderException;
import io.cici.cc.mybatis.lite.sql_source.scripting.XMLScriptBuilder;
import io.cici.cc.mybatis.lite.sql_source.scripting.tag.ChooseTag;
import io.cici.cc.mybatis.lite.sql_source.scripting.tag.Tag;

import java.util.ArrayList;
import java.util.List;

public class ChooseTagHandler implements TagHandler {
    private final XMLScriptBuilder xmlScriptBuilder;

    public ChooseTagHandler(XMLScriptBuilder xmlScriptBuilder) {
        this.xmlScriptBuilder = xmlScriptBuilder;
        // Prevent Synthetic Access
    }

    @Override
    public void handle(io.cici.cc.mybatis.lite.parse.Node nodeToHandle, List<Tag> tagList) {
        List<Tag> whenTags = new ArrayList<>();
        List<Tag> otherwiseTags = new ArrayList<>();
        handleWhenOtherwiseNodes(nodeToHandle, whenTags, otherwiseTags);
        Tag defaultTag = getDefaultSqlNode(otherwiseTags);
        ChooseTag chooseTag = new ChooseTag(whenTags, defaultTag);
        tagList.add(chooseTag);
    }

    private void handleWhenOtherwiseNodes(io.cici.cc.mybatis.lite.parse.Node chooseNode, List<Tag> ifTags,
                                          List<Tag> defaultTags) {
        List<io.cici.cc.mybatis.lite.parse.Node> children = chooseNode.getChildNodeList();
        for (io.cici.cc.mybatis.lite.parse.Node child : children) {
            String nodeName = child.getNode().getNodeName();
            TagHandler handler = xmlScriptBuilder.tagToTagHandlerMap.get(nodeName);
            if (handler instanceof IfTagHandler) {
                handler.handle(child, ifTags);
            } else if (handler instanceof OtherwiseTagHandler) {
                handler.handle(child, defaultTags);
            }
        }
    }

    private Tag getDefaultSqlNode(List<Tag> defaultTags) {
        Tag defaultTag = null;
        if (defaultTags.size() == 1) {
            defaultTag = defaultTags.get(0);
        } else if (defaultTags.size() > 1) {
            throw new BuilderException("Too many default (otherwise) elements in choose statement.");
        }
        return defaultTag;
    }
}
